package com.own.business.system.user.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.own.business.login.core.hook.GetUserNameHook;
import com.own.business.system.user.business.core.SystemUserInfoUpdatePhoneSpringHook;
import com.own.business.system.user.business.hook.AfterRegisterUserHook;
import com.own.business.system.user.business.service.SystemUserInfoService;
import com.own.business.system.user.entity.bo.SystemUserInfoBo;
import com.own.business.system.user.entity.map.SystemUserInfoMapVo;
import com.own.business.system.user.entity.po.SystemUser;
import com.own.business.system.user.entity.po.SystemUserInfo;
import com.own.business.system.user.entity.query.SystemUserInfoQuery;
import com.own.business.system.user.entity.vo.SystemUserInfoVo;
import com.own.business.system.user.mapper.SystemUserInfoMapper;
import com.own.component.common.base.service.impl.AbstractBaseService;
import com.own.component.common.hook.BaseUserDetailHook;
import com.own.component.common.login.user.BaseLoginUser;
import com.own.component.store.core.Store;
import com.own.component.store.core.util.StoreKeyUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.UUID;

/**
 * SystemUserInfoServiceImpl
 *
 * @author chenxueli
 * @date 2021/06/24 15:46:54
 */
@Slf4j
@Service
public class SystemUserInfoServiceImpl extends AbstractBaseService<
        SystemUserInfo,
        SystemUserInfoBo,
        SystemUserInfoVo,
        SystemUserInfoMapVo,
        SystemUserInfoQuery,
        SystemUserInfoMapper
        > implements
        SystemUserInfoService,
        BaseUserDetailHook,
        AfterRegisterUserHook,
        GetUserNameHook {

    @Resource
    private SystemUserInfoMapper systemUserInfoMapper;

    @Resource
    private SystemUserInfoUpdatePhoneSpringHook systemUserInfoUpdatePhoneSpringHook;

    @Resource
    private Store<String> store;

    /**
     * 获取查询条件
     *
     * @param query 查询条件
     * @return 查询条件对象
     */
    @Override
    public LambdaQueryWrapper<SystemUserInfo> lambdaQueryWrapper(SystemUserInfoQuery query) {
        return super.lambdaQueryWrapper(query)
                .like(StringUtils.isNotBlank(query.getPhone()), SystemUserInfo::getPhone, query.getPhone())
                .eq(query.getType() != null, SystemUserInfo::getType, query.getType())
                .orderByDesc(SystemUserInfo::getGmtCreate, SystemUserInfo::getId);
    }

    /**
     * 获取详情信息
     *
     * @param loginUser 登录的用户信息
     * @return 获取到的内容
     */
    @Override
    public Object detail(BaseLoginUser loginUser) {
        var po = getPoById(SystemUserInfo::getFkUserId, loginUser.userId(), false);
        if (po != null) {
            return new SystemUserInfoMapVo(po);
        }
        var info = new SystemUserInfo()
                .setName(loginUser.userName())
                .setGender(0)
                .setIntroduction("")
                .setFkUserId(loginUser.userId());
        systemUserInfoMapper.insert(info);
        return new SystemUserInfoMapVo(info);
    }

    /**
     * 根据邮箱获取用户信息
     *
     * @param email 邮箱
     * @return 用户信息
     */
    @Override
    public SystemUserInfo getByEmail(String email) {
        var wrapper = lambdaQueryWrapper().eq(SystemUserInfo::getEmail, email);
        return getOneByWrapper(wrapper);
    }

    /**
     * 根据手机号获取用户信息
     *
     * @param phone 手机号
     * @return 用户信息
     */
    @Override
    public SystemUserInfo getByPhone(String phone) {
        var wrapper = lambdaQueryWrapper().eq(SystemUserInfo::getPhone, phone);
        return getOneByWrapper(wrapper);
    }

    /**
     * 根据用户名称获取用户信息
     *
     * @param name 用户名称
     * @return 用户信息
     */
    @Override
    public SystemUserInfo getByName(String name) {
        var wrapper = lambdaQueryWrapper().eq(SystemUserInfo::getName, name);
        return getOneByWrapper(wrapper);
    }

    /**
     * 根据用户id获取用户信息
     *
     * @param userId 用户id
     * @return 用户信息
     */
    @Override
    public SystemUserInfo getByUserId(Long userId) {
        var wrapper = lambdaQueryWrapper().eq(SystemUserInfo::getFkUserId, userId);
        return getOneByWrapper(wrapper);
    }

    /**
     * 根据用户id获取用户手机号信息
     *
     * @param userId 用户id
     * @return 用户手机号
     */
    @Override
    public String getPhoneByUserId(Long userId) {
        var wrapper = lambdaQueryWrapper().select(SystemUserInfo::getPhone).eq(SystemUserInfo::getFkUserId, userId);
        var po = getOneByWrapper(wrapper);
        return po == null ? null : po.getPhone();
    }

    /**
     * 修改头像
     *
     * @param userId 用户id
     * @param avatar 头像地址
     */
    @Override
    public void updateAvatar(Long userId, String avatar) {
        var updateWrapper = new LambdaUpdateWrapper<SystemUserInfo>()
                .eq(SystemUserInfo::getFkUserId, userId)
                .set(SystemUserInfo::getAvatar, avatar);
        systemUserInfoMapper.update(null, updateWrapper);
    }

    /**
     * 修改昵称
     *
     * @param userId 用户id
     * @param name   昵称
     */
    @Override
    public void updateName(Long userId, String name) {
        var updateWrapper = new LambdaUpdateWrapper<SystemUserInfo>()
                .eq(SystemUserInfo::getFkUserId, userId)
                .set(SystemUserInfo::getName, name);
        systemUserInfoMapper.update(null, updateWrapper);
        // 清除用户名称缓存
        clearUserNameCache(userId);
    }

    /**
     * 修改手机号
     *
     * @param userId 用户id
     * @param phone  手机号
     */
    @Override
    public void updatePhone(Long userId, String phone) {
        var wrapper = lambdaQueryWrapper().eq(SystemUserInfo::getFkUserId, userId);
        var po = getOneByWrapper(wrapper);
        if (po == null) {
            return;
        }
        systemUserInfoUpdatePhoneSpringHook.before(userId, po.getPhone(), phone);
        var updateWrapper = new LambdaUpdateWrapper<SystemUserInfo>()
                .eq(SystemUserInfo::getFkUserId, userId)
                .set(SystemUserInfo::getPhone, phone);
        systemUserInfoMapper.update(null, updateWrapper);
        systemUserInfoUpdatePhoneSpringHook.after(userId, po.getPhone(), phone);
    }

    /**
     * 修改邮箱
     *
     * @param userId 用户id
     * @param email  邮箱
     */
    @Override
    public void updateEmail(Long userId, String email) {
        var updateWrapper = new LambdaUpdateWrapper<SystemUserInfo>()
                .eq(SystemUserInfo::getFkUserId, userId)
                .set(SystemUserInfo::getEmail, email);
        systemUserInfoMapper.update(null, updateWrapper);
    }

    /**
     * 注册后执行
     *
     * @param user 用户信息
     */
    @Override
    public void afterRegisterUser(SystemUser user) {
        var info = new SystemUserInfo()
                .setName("用户_" + UUID.randomUUID().toString().substring(0, 8))
                .setGender(0)
                .setType(user.getType())
                .setIntroduction("")
                .setFkUserId(user.getId());
        systemUserInfoMapper.insert(info);
    }

    /**
     * 用户详情key
     *
     * @return key
     */
    @Override
    public String detailKey() {
        return "info";
    }

    /**
     * 根据用户获取用户名称
     *
     * @param userId 用户id
     * @return 用户名称
     */
    @Override
    public String getUserName(Long userId) {
        var info = getByUserId(userId);
        return info == null ? "" : info.getName();
    }

    /**
     * 顺序
     *
     * @return 顺序
     */
    @Override
    public int getUserNameOrder() {
        return 1;
    }

    /**
     * 生效的账号类型
     *
     * @return 账号类型 1=普通账号 2=管理员
     */
    @Override
    public Integer effectiveAccountType() {
        return null;
    }

    /**
     * 清除用户名称缓存
     *
     * @param userId 用户id
     */
    @Override
    public void clearUserNameCache(Long userId) {
        store.value().remove(StoreKeyUtil.build("username", userId));
    }

    /**
     * 根据用户ids查询信息
     *
     * @param userIdList 用户id列表
     * @return 用户信息列表
     */
    @Override
    public List<SystemUserInfo> listByUserIdList(Collection<Long> userIdList) {
        if (userIdList == null || userIdList.isEmpty()) {
            return List.of();
        }
        var wrapper = lambdaQueryWrapper().in(SystemUserInfo::getFkUserId, userIdList);
        return listByWrapper(wrapper);
    }

}
